package com.gusto.test.semantic;


import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gusto.engine.colfil.Distance;
import com.gusto.engine.colfil.neighborhood.storedistance.DistancePersistenceDAO;
import com.gusto.engine.colfil.service.CollaborativeService;

public class TstDistance {
	
	private CollaborativeService collaborativeService;
	private DistancePersistenceDAO distanceDAO;
	
	@Before
	public void setUp() throws Exception {
		ApplicationContext factory = new ClassPathXmlApplicationContext("colfil-context.xml");
		this.collaborativeService = (CollaborativeService)factory.getBean("collaborativeService");
		this.distanceDAO = (DistancePersistenceDAO)factory.getBean("distanceDAO");
	}
	
	@After
	public void tearDown() throws Exception {
	}
	
	// FIXME
	// distanceDAO.clean();
	
	@Test
	public void testCalculateDistance() {
		Distance distance;
		
		distance = collaborativeService.calculateUserDistance(173, 740);
		assertEquals(new Integer(7), distance.getCount());
		assertEquals(new Double(0.8193464903987026), distance.getDistance());
		
		distance = collaborativeService.calculateUserDistance(898, 408);
		assertEquals(new Integer(6), distance.getCount());
		assertEquals(new Double(0.8542977006895834), distance.getDistance());
		
		distance = collaborativeService.calculateUserDistance(791, 740);
		assertEquals(new Integer(5), distance.getCount());
		assertEquals(new Double(0.05834103161624449), distance.getDistance());
		
		distance = collaborativeService.calculateUserDistance(898, 740);
		assertEquals(new Integer(6), distance.getCount());
		assertEquals(new Double(-0.6831300510639733), distance.getDistance());
	}
	
	@Test
	public void testNeighborhood() {
		for (Distance dd : distanceDAO.getNearUsers(740)) {
			System.out.println(dd);
		}
		
		for (Distance dd : distanceDAO.getNearItems(50)) {
			System.out.println(dd);
		}
	}
	
	@Test
	public void testUpdateDistanceUser() {
		//Distance d = collaborativeService.calculateUserDistance(173, 740);
		Distance dist = collaborativeService.calculateUserDistance(898, 740);
		
		Distance dbd = new Distance(dist.getId1(), dist.getId2(), dist.getCount(), dist.getDistance());
		distanceDAO.updateUserDistance(dist.getId1(), dist.getId2(), dbd);
		
		List<Distance> distances = distanceDAO.getNearUsers(898);
		Distance theOtherUserDist = null;
		for (Distance d : distances) {
			if (d.getId1().equals(740L) || d.getId2().equals(740L)) {
				theOtherUserDist = d;
			}
		}
		assertEquals(dist.getDistance(), theOtherUserDist.getDistance());
	}
	
	@Test
	public void testUpdateDistanceItem() {
		Distance dist = collaborativeService.calculateItemDistance(50, 181);
		
		Distance dbd = new Distance(dist.getId1(), dist.getId2(), dist.getCount(), dist.getDistance());
		distanceDAO.updateItemDistance(dist.getId1(), dist.getId2(), dbd);
		
		List<Distance> distances = distanceDAO.getNearItems(50);
		Distance theOtherItemDist = null;
		for (Distance d : distances) {
			if (d.getId1().equals(181L) || d.getId2().equals(181L)) {
				theOtherItemDist = d;
			}
		}
		assertEquals(dist.getDistance(), theOtherItemDist.getDistance());
	}
	
	
}
